<template>
	<view class="text-ellipsis" :class="[!isExpand && 'un-expand']" :style="{lineHeight: lineHeight + 'rpx'}">
		<view ref="contentEl" class="text-ellipsis-content"
			:style="{ maxHeight: isExpand ? 'none' : `${maxHeight}px` }">
			<view id="contentEl">
				<!-- 占位符 -->
				<text class="text-ellipsis-placeholder" :style="{height: placeholderHeight + 'px'}"></text>
				<!-- 内容+操作按钮,不留空格 -->
				{{isExpand ? content : '' }}
				<text v-if="isEll" ref="tailEl" class="text-ellipsis-tail" id="tailEl">
					<text class="text-ellipsis-dot" v-if="!isExpand">{{dot}}</text>
					<text v-if="!single" class="text-ellipsis-action" @click="onActionClick">{{actionText}}</text>
				</text>{{isExpand ? '' : content}}
			</view>
		</view>

		<text v-if="single && isEll" class="text-ellipsis-action" @click="onActionClick">{{actionText}}</text>
	</view>
</template>

<script>
	function toNum(val) {
		if (!val) return 0

		return parseFloat(val)
	}
	export default {
		data() {
			return {
				isEll: false,
				isExpand: false,
				placeholderHeight: 0,
				maxHeight: 0,
				lazyToCalc: false
			}
		},
		props: {
			content: {
				type: String,
				default: '',
				required: true
			},
			// 省略行数
			rows: {
				type: Number,
				default: 5
			},
			// 展开文案
			expandText: {
				type: String,
				default: '展开'
			},
			// 收起文案
			collapseText: {
				type: String,
				default: '收起'
			},
			// 省略点
			dot: {
				type: String,
				default: '...'
			},
			single: {
				type: Boolean,
				default: false
			},
			lineHeight: {
				type: [Number, String],
				default: 36,
			}
		},
		computed: {
			actionText() {
				return this.isExpand ? this.collapseText : this.expandText
			}
		},
		watch: {
			content() {
				this.calcEll()
			},
			rows() {
				this.calcEll()
			}
		},
		mounted() {
			this.calcEll()
		},
		methods: {
			calcEll() {
				this.$nextTick(() => {
					setTimeout(() => {
						const query = uni.createSelectorQuery().in(this);
						query
							.select("#contentEl")
							.boundingClientRect((data) => {
								const lineHeight = uni.upx2px(this.lineHeight)
								this.maxHeight = toNum(lineHeight) * this.rows
								this.isEll = data.height > this.maxHeight
								if (this.isEll) {
									if (this.isExpand) {
										this.lazyToCalc = true
										return
									}
									this.$nextTick(() => {
										const query1 = uni.createSelectorQuery().in(this);
										query1
											.select("#tailEl").boundingClientRect((res) => {
												this.placeholderHeight = this.maxHeight -
													res.height
											}).exec()
									})


								}

							})
							.exec();
					}, 0)

				})
			},
			onActionClick() {
				this.isExpand = !this.isExpand
				if (this.lazyToCalc) {
					this.lazyToCalc = false
					this.calcEll()
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	.text-ellipsis {
		font-size: 26rpx;

		&.un-expand {
			.text-ellipsis-placeholder {
				float: right;
			}

			.text-ellipsis-tail {
				float: right;
				clear: both;
			}
		}

		&.is-single {
			.text-ellipsis-action {
				display: block;
			}
		}
	}

	.text-ellipsis-content {
		overflow: hidden;
		text-overflow: ellipsis;
		word-wrap: break-word;
		word-break: break-word;
		text-justify: inter-character;
		text-align: justify;
		white-space: pre-line;
		height: fit-content;
	}

	.text-ellipsis-action {
		color: #409eff;
	}
</style>